package com.zeyu.framework.core.web.interceptor;

import com.google.common.collect.Maps;

import com.zeyu.framework.core.security.utils.SecurityUtils;
import com.zeyu.framework.core.web.servlet.Servlets;
import com.zeyu.framework.modules.sys.entity.Menu;
import com.zeyu.framework.modules.sys.utils.UserUtils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 全局拦截器, 目前返回整体日志、告警、订单信息
 * Created by zeyuphoenix on 2016/3/27.
 */
public class GlobalInterceptor implements HandlerInterceptor {

    // ================================================================
    // Constants
    // ================================================================

    // ================================================================
    // Fields
    // ================================================================

    /**
     * TODO 全局数据，为了防止每次获取，需要保存在内存中直接取得
     */
    // logTotalGlobal      String     log总条数
    private String logTotalGlobal = "23149";
    // logListGlobal       String     log总列表
    private String logListGlobal = "1300, 1877, 2500, 2577, 2000, 2100, 3000, 2700, 3631, 2471, 2700, 3631, 2471";
    // alarmTotalGlobal    String     alarm总条数
    private String alarmTotalGlobal = "4528";
    // alarmListGlobal     String     alarm列表
    private String alarmListGlobal = "210,130,20,430,220,410,230,100,220,40, 570, 410";
    // orderTotalGlobal    String     order总条数
    private String orderTotalGlobal = "25";
    // orderListGlobal     String     order列表
    private String orderListGlobal = "110,150,300,130,400,240,220,310,220,300, 270, 210";

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    /**
     * preHandle方法是进行处理器拦截用的，顾名思义，该方法将在Controller处理之前进行调用，SpringMVC中的
     * Interceptor拦截器是链式的，可以同时存在多个Interceptor，然后SpringMVC会根据声明的前后顺序一个接
     * 一个的执行，而且所有的Interceptor中的preHandle方法都会在Controller方法调用之前调用。
     * SpringMVC的这种Interceptor链式结构也是可以进行中断的，这种中断方式是令preHandle的返
     * 回值为false，当preHandle的返回值为false的时候整个请求就结束了。
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response, Object handler) throws Exception {
        return true;
    }

    /**
     * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。
     * postHandle是进行处理器拦截用的，它的执行时间是在处理器进行处理之后，也就是在Controller的方法调用之后执行，
     * 但是它会在DispatcherServlet进行视图的渲染之前执行，也就是说在这个方法中你可以对ModelAndView进行操作。这
     * 个方法的链式结构跟正常访问的方向是相反的，也就是说先声明的Interceptor拦截器该方法反而会后调用。
     */
    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
        String url = request.getRequestURI();

        if (SecurityUtils.getPrincipal() == null) {
            // 非登录不提供全局数据
            return;
        }

        if (!StringUtils.contains(url, "/static/")) {
            // 静态文件也不需要设置
            if (!Servlets.isAjaxRequest(request)) {
                // 非ajax和手机请求才走这里
                Map<String, String> globalInfoMap = Maps.newHashMap();
                // 全局信息
                Menu menu = UserUtils.getMenuByUri(url);
                // iconClassGlobal     String     标题icon样式,一般用font awesome
                globalInfoMap.put("iconClass", menu.getIcon());
                // titleGlobal         String     一级标题
                globalInfoMap.put("title", menu.getParentName());
                // subtitleGlobal      String     子标题
                globalInfoMap.put("subtitle", menu.getName());
                // 日志统计
                globalInfoMap.put("logTotal", logTotalGlobal);
                globalInfoMap.put("logList", logListGlobal);
                // 告警统计
                globalInfoMap.put("alarmTotal", alarmTotalGlobal);
                globalInfoMap.put("alarmList", alarmListGlobal);
                // 订单统计
                globalInfoMap.put("orderTotal", orderTotalGlobal);
                globalInfoMap.put("orderList", orderListGlobal);

                if (modelAndView != null)
                    modelAndView.addObject("globalInfo", globalInfoMap);
            }
        }

    }

    /**
     * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。
     * 该方法将在整个请求完成之后，也就是DispatcherServlet渲染了视图执行，这个方法的主要作用是用于清理资源的，当然
     * 这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
    }

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================
}
